<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>观察者模式4</title>
</head>
<body>
<script>
    //发布者的欧早函数，定义一个类型维数组的属性，用来保存订阅者的引用
    function Publisher(){
        this.subscribers=[];
    }
    //投送方法，注意遍历每一个订阅者
    Publisher.prototype.deliver=function(data){
        this.subscribers.forEach(function(fn){
            //console.log(data);
            fn(data);
        });
        //返回this。能让他使用链式
        return this;
    };
    //订阅方法
    Function.prototype.subscribe=function(publisher){
        var that=this;
        //some是判断publisher中是否有满足条件的，返回true，或者false
        var alreadyExists=publisher.subscribers.some(function(el){
            //console.log(this);
            return el===that;
        });
        //根据是否有这个值来决定是否为指定的发布者添加一个订阅者，如果原来没有则为他添加，有则不添加。
        if(!alreadyExists){
            publisher.subscribers.push(this);
        }
        return this;
    };
    //退订方法,也就是不对这个订阅者发布任何消息，也就是把他过滤掉了，但是我觉得这种方法写的不太好，你虽然不对他
    //发布，但是他还保存在那里呀？？？
    Function.prototype.unsubscribe=function(publisher){
        var that=this;
        publisher.subscribers=publisher.subscribers.filter(function(el){
            return el !==that;
        });
        return this;
    };
    var publisherObject1=new Publisher();
    //var publisherObject2=new Publisher();
    var observerObject1=function(data){
        console.log(data);
        arguments.callee.unsubscribe(publisherObject1)
    };
    var observerObject2=function(data){
        console.log(data+"hello world");
        arguments.callee.unsubscribe(publisherObject1)
    };
    observerObject1.subscribe(publisherObject1);
    publisherObject1.deliver("hello world");
   // publisherObject1.deliver("你好啊世界222");
    observerObject2.subscribe(publisherObject1);
    //publisherObject2.deliver("你好啊世界");
    observerObject2.unsubscribe(publisherObject1);
    //可还是一取消就把所有的都取消了
    publisherObject1.deliver("hello world1");
    publisherObject1.deliver("hello world2");
</script>
</body>
</html>